#include "easyx.h"
#include "easyc.h"

#define ExC extern "C"


ExC HWND graphCreate(int width, int height) {
    return initgraph(width, height, 0);
}

ExC HWND graphInit(int width, int height, int flag) {
    return initgraph(width, height, flag);
}

ExC void graphClose() {
    closegraph();
}

ExC void graphClear() {
    cleardevice();
}

ExC void graphReset() {
    graphdefaults();
}

ExC int graphGetWidth() {
    return getwidth();
}

ExC int graphGetHeight() {
    return getheight();
}

ExC HWND graphGetHWnd() {
    return GetHWnd();
}


ExC void cliprgnSet(HRGN hrgn) {
    setcliprgn(hrgn);
}

ExC void cliprgnClear() {
    clearcliprgn();
}


ExC __LINESTYLE lineStyleInit(){
    return static_cast<__LINESTYLE>(new LINESTYLE());
}

ExC __LINESTYLE lineStyleCopy(__LINESTYLE style) {
    if (style == NULL) {
        return NULL;
    }
    LINESTYLE temp = *static_cast<LINESTYLE*>(style);
    return static_cast<__LINESTYLE>(new LINESTYLE(temp));
}

ExC void lineStyleFree(__LINESTYLE style) {
    if (style != NULL) {
        delete static_cast<LINESTYLE*>(style);
    }
}


ExC __FILLSTYLE fillStyleInit() {
    return static_cast<__FILLSTYLE>(new FILLSTYLE());
}

ExC __FILLSTYLE fillStyleCopy(__FILLSTYLE style) {
    if (style == NULL) {
        return NULL;
    }
    FILLSTYLE temp = *static_cast<FILLSTYLE*>(style);
    return static_cast<__FILLSTYLE>(new FILLSTYLE(temp));
}

ExC void fillStyleFree(__FILLSTYLE style) {
    if (style != NULL) {
        delete static_cast<FILLSTYLE*>(style);
    }
}


ExC __IMAGE imageInit(int width, int height) {
    return static_cast<__IMAGE>(new IMAGE(width, height));
}

ExC __IMAGE imageCopy(__IMAGE img) {
    if (img == NULL) {
        return NULL;
    }
    IMAGE temp = *static_cast<IMAGE*>(img);
    return static_cast<__IMAGE>(new IMAGE(temp));
}

ExC void imageFree(__IMAGE img) {
    if (img != NULL) {
        delete static_cast<IMAGE*>(img);
    }
}

ExC void imageResize(__IMAGE img, int width, int height) {
    if (img != NULL) {
        static_cast<IMAGE*>(img)->Resize(width, height);
    }
}

ExC int imageGetWidth(__IMAGE img) {
    if (img == NULL) {
        return 0;
    }
    return static_cast<IMAGE*>(img)->getwidth();
}

ExC int imageGetHeight(__IMAGE img) {
    if (img == NULL) {
        return 0;
    }
    return static_cast<IMAGE*>(img)->getheight();
}


ExC void originSet(int x, int y) {
    setorigin(x, y);
}

ExC void aspectratioGet(float *pxasp, float *pyasp) {
    getaspectratio(pxasp, pyasp);
}

ExC void aspectratioSet(float xasp, float yasp) {
    setaspectratio(xasp, yasp);
}


ExC int rop2Get() {
    return getrop2();
}

ExC void rop2Set(int mode) {
    setrop2(mode);
}

ExC int polyfillModeGet() {
    return getpolyfillmode();
}

ExC void polyfillModeSet(int mode) {
    setpolyfillmode(mode);
}


ExC COLORREF lineColorGet() {
    return getlinecolor();
}

ExC void lineColorSet(COLORREF color) {
    setlinecolor(color);
}

ExC COLORREF textColorGet() {
    return gettextcolor();
}

ExC void textColorSet(COLORREF color) {
    settextcolor(color);
}

ExC COLORREF fillColorGet() {
    return getfillcolor();
}

ExC void fillColorSet(COLORREF color) {
    setfillcolor(color);
}

ExC COLORREF bkColorGet() {
    return getbkcolor();
}

ExC void bkColorSet(COLORREF color) {
    setbkcolor(color);
}

ExC int bkModeGet() {
    return getbkmode();
}

ExC void bkModeSet(int mode) {
    setbkmode(mode);
}


ExC COLORREF RGB2GRAY(COLORREF rgb) {
    return RGBtoGRAY(rgb);
}

ExC void RGB2HSL(COLORREF rgb, float *H, float *S, float *L) {
    RGBtoHSL(rgb, H, S, L);
}

ExC void RGB2HSV(COLORREF rgb, float *H, float *S, float *V) {
    RGBtoHSV(rgb, H, S, V);
}

ExC COLORREF HSL2RGB(float H, float S, float L) {
    return HSLtoRGB(H, S, L);
}

ExC COLORREF HSV2RGB(float H, float S, float V) {
    return HSVtoRGB(H, S, V);
}


ExC COLORREF getPixel(int x, int y) {
    return getpixel(x, y);
}

ExC void putPixel(int x, int y, COLORREF color) {
    putpixel(x, y, color);
}


ExC void lineDraw(int x1, int y1, int x2, int y2) {
    line(x1, y1, x2, y2);
}


ExC void rectangleDraw(int left, int top, int right, int bottom) {
    rectangle(left, top, right, bottom);
}

ExC void rectangleFill(int left, int top, int right, int bottom) {
    fillrectangle(left, top, right, bottom);
}

ExC void rectangleSolid(int left, int top, int right, int bottom) {
    solidrectangle(left, top, right, bottom);
}

ExC void rectangleClear(int left, int top, int right, int bottom) {
    clearrectangle(left, top, right, bottom);
}


ExC void circleDraw(int x, int y, int radius) {
    circle(x, y, radius);
}

ExC void circleFill(int x, int y, int radius) {
    fillcircle(x, y, radius);
}

ExC void circleSolid(int x, int y, int radius) {
    solidcircle(x, y, radius);
}

ExC void circleClear(int x, int y, int radius) {
    clearcircle(x, y, radius);
}


ExC void ellipseDraw(int left, int top, int right, int bottom) {
    ellipse(left, top, right, bottom);
}

ExC void ellipseFill(int left, int top, int right, int bottom) {
    fillellipse(left, top, right, bottom);
}

ExC void ellipseSolid(int left, int top, int right, int bottom) {
    solidellipse(left, top, right, bottom);
}

ExC void ellipseClear(int left, int top, int right, int bottom) {
    clearellipse(left, top, right, bottom);
}

ExC void roundRectDraw(int left, int top, int right, int bottom, int ellipseWidth, int ellipseHeight) {
    roundrect(left, top, right, bottom, ellipseWidth, ellipseHeight);
}

ExC void roundRectFill(int left, int top, int right, int bottom, int ellipseWidth, int ellipseHeight) {
    fillroundrect(left, top, right, bottom, ellipseWidth, ellipseHeight);
}

ExC void roundRectSolid(int left, int top, int right, int bottom, int ellipseWidth, int ellipseHeight) {
    solidroundrect(left, top, right, bottom, ellipseWidth, ellipseHeight);
}

ExC void roundRectClear(int left, int top, int right, int bottom, int ellipseWidth, int ellipseHeight) {
    clearroundrect(left, top, right, bottom, ellipseWidth, ellipseHeight);
}


ExC void pieArc(int left, int top, int right, int bottom, double stangle, double endangle) {
    arc(left, top, right, bottom, stangle, endangle);
}

ExC void pieDraw(int left, int top, int right, int bottom, double stangle, double endangle) {
    pie(left, top, right, bottom, stangle, endangle);
}

ExC void pieFill(int left, int top, int right, int bottom, double stangle, double endangle) {
    fillpie(left, top, right, bottom, stangle, endangle);
}

ExC void pieSolid(int left, int top, int right, int bottom, double stangle, double endangle) {
    solidpie(left, top, right, bottom, stangle, endangle);
}

ExC void pieClear(int left, int top, int right, int bottom, double stangle, double endangle) {
    clearpie(left, top, right, bottom, stangle, endangle);
}


ExC void polyLineDraw(const POINT *points, int num) {
    polyline(points, num);
}

ExC void polygonDraw(const POINT *points, int num) {
    polygon(points, num);
}

ExC void polygonFill(const POINT *points, int num) {
    fillpolygon(points, num);
}

ExC void polygonSolid(const POINT *points, int num) {
    solidpolygon(points, num);
}

ExC void polygonClear(const POINT *points, int num) {
    clearpolygon(points, num);
}


ExC void bezierDraw(const POINT *points, int num) {
    polybezier(points, num);
}


ExC void floodFill(int x, int y, COLORREF color, int filltype) {
    floodfill(x, y, color, filltype);
}


ExC void strPut(int x, int y, char *str) {
    outtextxy(x, y, str);
}

ExC void charPut(int x, int y, char c) {
    outtextxy(x, y, c);
}

ExC int strWidth(char *str) {
    return textwidth(str);
}

ExC int charWidth(char c) {
    return textwidth(c);
}

ExC int strHeight(char *str) {
    return textheight(str);
}

ExC int charHeight(char c) {
    return textheight(c);
}

ExC int strDraw(char* str, RECT* pRect, UINT uFormat) {
    return drawtext(str, pRect, uFormat);
}

ExC int charDraw(char c, RECT* pRect, UINT uFormat) {
    return drawtext(c, pRect, uFormat);
}


void imageLoad(__IMAGE pDstImg, char* pImgFile){
    IMAGE *img = static_cast<IMAGE*>(pDstImg);
    loadimage(img, pImgFile);
}

void imageCarry(__IMAGE pDstImg, char* pImgFile, int nWidth, int nHeight, bool bResize){
    IMAGE *img = static_cast<IMAGE*>(pDstImg);
    loadimage(img, pImgFile, nWidth, nHeight, bResize);
}

void imageSave(char* pImgFile, __IMAGE pImg){
    IMAGE *img = static_cast<IMAGE*>(pImg);
    saveimage(pImgFile, img);
}

void imageGet(__IMAGE pDstImg, int srcX, int srcY, int srcWidth, int srcHeight){
    IMAGE *img = static_cast<IMAGE*>(pDstImg);
    getimage(img, srcX, srcY, srcWidth, srcHeight);
}

void imagePut(int dstX, int dstY, const __IMAGE pSrcImg, DWORD dwRop){
    IMAGE *srcImg = static_cast<IMAGE*>(pSrcImg);
    putimage(dstX, dstY, srcImg, dwRop);
}

void imageDraw(int dstX, int dstY, int dstWidth, int dstHeight, const __IMAGE pSrcImg, int srcX, int srcY, DWORD dwRop){
    IMAGE *srcImg = static_cast<IMAGE*>(pSrcImg);
    putimage(dstX, dstY, dstWidth, dstHeight, srcImg, srcX, srcY, dwRop);
}

void imageRotate(__IMAGE dstimg, __IMAGE srcimg, double radian){
    IMAGE *dstImg = static_cast<IMAGE*>(dstimg);
    IMAGE *srcImg = static_cast<IMAGE*>(srcimg);
    rotateimage(dstImg, srcImg, radian);
}

void imagePivot(__IMAGE dstimg, __IMAGE srcimg, double radian, COLORREF bkcolor, bool autosize, bool highquality){
    IMAGE *dstImg = static_cast<IMAGE*>(dstimg);
    IMAGE *srcImg = static_cast<IMAGE*>(srcimg);
    rotateimage(dstImg, srcImg, radian, bkcolor, autosize, highquality);
}


DWORD* imageGetBuffer(__IMAGE pImg){
    IMAGE *img = static_cast<IMAGE*>(pImg);
    return GetImageBuffer(img);
}

__IMAGE imageGetWorking(){
    return static_cast<__IMAGE>(GetWorkingImage());
}

void imageSetWorking(__IMAGE pImg){
    IMAGE *img = static_cast<IMAGE*>(pImg);
    SetWorkingImage(img);
}

HDC imageGetHDC(__IMAGE pImg){
    IMAGE *img = static_cast<IMAGE*>(pImg);
    return GetImageHDC(img);
}


ExC const char* getEasyXVersion() {
    return GetEasyXVer();
}


ExC ExMsg messageGet(){
    return messageFilter(-1);
}

ExC ExMsg messageFilter(BYTE filter){
    ExMessage from = getmessage(filter);
    ExMsg to;
    memcpy(&to, &from, sizeof(ExMsg));
    return to;
}

ExC void messageSave(ExMsg *msg){
    messageSelect(msg, -1);
}

ExC void messageSelect(ExMsg *msg, BYTE filter){
    ExMessage from;
    getmessage(&from, filter);
    memcpy(msg, &from, sizeof(ExMsg));
}

ExC bool messagePeek(ExMsg *msg, BYTE filter){
    ExMessage from;
    bool result = peekmessage(&from, filter);
    memcpy(msg, &from, sizeof(ExMsg));
    return result;
}

ExC void messageFlush(BYTE filter){
    flushmessage(filter);
}

void messageClear(){
    flushmessage();
}


ExC void batchDrawBegin() {
    BeginBatchDraw();
}

ExC void batchDrawFlush() {
    FlushBatchDraw();
}

ExC void batchDrawEnd() {
    EndBatchDraw();
}